package key.w8.boot.reference;

import com.k8.common.constants.CommonKeyConstants;
import com.k8.common.event.EventDeployer;
import com.k8.common.executor.ExecutorRepository;
import com.k8.common.factroy.BeanFactory;
import com.k8.common.factroy.loader.ExtensionDirector;
import com.k8.common.util.StrUtil;
import com.k8.registry.RegistryManager;
import com.k8.registry.config.ReferenceBase;
import com.k8.rpc.invoke.InvokerManager;
import com.k8.rpc.url.URL;
import com.k8.rpc.util.ConfigUtil;
import key.w8.boot.contenxt.ReferenceContext;
import key.w8.boot.properties.ConsumerAutoConfigurationProperties;
import key.w8.boot.properties.Registry;
import key.w8.boot.util.ConvertURLUtil;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.List;
import java.util.concurrent.ExecutorService;

/**
 * @Author: k8
 * @CreateTime: 2025-08-17
 * @Version: 1.0
 */
public class ReferenceBuilder implements ApplicationContextAware{
    private ConsumerAutoConfigurationProperties k8ConfigProperties;
    private BeanFactory beanFactory;
    private ApplicationContext applicationContext;



    public Object build(ReferenceContext referenceContext) {
        List<Registry> registries = k8ConfigProperties.getRegistries();
        URL systemConfigUrl = ConfigUtil.mapConfigToConstants(k8ConfigProperties);
        systemConfigUrl.setSide(CommonKeyConstants.CONSUMER);
        //***
        beanFactory.getOrRegistryBean(RegistryManager.class);
        beanFactory.getOrRegistryBean(InvokerManager.class);
        //***
        ExtensionDirector extensionDirector = beanFactory.getExtensionDirector();
        systemConfigUrl.setExtensionAccessor(beanFactory.getExtensionDirector());
        ExecutorRepository defaultExecutorRepository = extensionDirector.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
        ExecutorService executorService = defaultExecutorRepository.getExecutorService(systemConfigUrl);
        EventDeployer eventDeployer = new EventDeployer(executorService);
        beanFactory.registryBean(eventDeployer);
        //定制化配置
        List<URL> registryConfigUrls = ConvertURLUtil.getRegistryConfigUrls(registries, systemConfigUrl, CommonKeyConstants.CONSUMER);
        ReferenceBase<Object> referenceBase = new ReferenceBase<>(beanFactory, registryConfigUrls, systemConfigUrl);
        String protocol = referenceContext.getProtocol();
        if (StrUtil.isEmpty(protocol)){
            protocol = k8ConfigProperties.getProtocol();
            if (StrUtil.isEmpty(protocol)) throw new IllegalStateException("At least one protocol is required.");
        }
        referenceBase.setType(referenceContext.getType())
                .setGroup(referenceContext.getGroup())
                .setVersion(referenceContext.getVersion())
                .setProtocol(protocol);
        return referenceBase.createProxy();
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        this.k8ConfigProperties = applicationContext.getBean(ConsumerAutoConfigurationProperties.class);
        this.beanFactory = applicationContext.getBean("consumerBeanFactory", BeanFactory.class);
    }
}
